package controller;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import util.EmailUtility;
import util.UrlUtility;

import bizlogic.BookingManager;
import bizlogic.FacilityManager;
import bizlogic.PriorityManager;
import bizlogic.UserManager;

import model.BookingDTO;
import model.FacilityDTO;
import model.PriorityDTO;
import model.UserDTO;
import model.error.BookingErrorDTO;

@WebServlet("/ProcessBooking")
public class ProcessBookingServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public ProcessBookingServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doShow(request, response);
	}
	
	private void doShow(HttpServletRequest req, HttpServletResponse res) {
		String type = req.getParameter("type");
		String facility = req.getParameter("facility");
		String startDate = req.getParameter("startDate");
		
		if ( type == null ) type = "ClassRoom";
		req.setAttribute("type", type);
		
		// Get the Facility List based on the Type
		FacilityManager fm = new FacilityManager();
		ArrayList<FacilityDTO> facilities = fm.getFacilityByType(type);
		PriorityManager pm = new PriorityManager();
		ArrayList<PriorityDTO> priorities = pm.getAll();
		
		SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy");
		
		BookingDTO book = new BookingDTO();
		book.setFacilityName(facility);
		
		try {
			book.setStartDate(df.parse(startDate));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		req.setAttribute("facilities", facilities);
		req.setAttribute("priorities", priorities);
		req.setAttribute("booking", book);
		
		UrlUtility.forwardPage(req, res, "/WEB-INF/MakeBooking.jsp");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doProcess(request, response);
	}
	
	private BookingErrorDTO doValidate(HttpServletRequest req, HttpServletResponse res) {
		// Get the data
		boolean valid = true;
		SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy");
		BookingErrorDTO err = new BookingErrorDTO();
		
		// Validation
		if ( req.getParameter("facility") == null ) {
			valid = false;
			err.setErrorFacility("Facility required!");
		} 
		
		System.out.println("Start: " + req.getParameter("startDate") + " | End: " + req.getParameter("endDate"));
		try {
			df.parse(req.getParameter("startDate"));
		} catch (ParseException e) {
			valid = false;
			err.setErrorStartDate("Invalid Start Date!");
		}
		
		try {
			df.parse(req.getParameter("endDate"));
		} catch (ParseException e) {
			valid = false;
			err.setErrorEndDate("Invalid Start Date!");
		}
		
		try {
			Integer.parseInt(req.getParameter("priority"));
		} catch (Exception e) {
			valid = false;
			err.setErrorPriority("Invalid Priority!");
		}
		
		if ( req.getParameter("userId").trim().isEmpty() ) {
			valid = false;
			err.setErrorUserId("Required User ID!");
		}
		
		if ( req.getParameter("reason").trim().isEmpty() ) {
			valid = false;
			err.setErrorReason("Reason required!");
		} 

		if ( req.getParameter("contactDetail") == null || req.getParameter("contactDetail").trim().isEmpty() ) {
			valid = false;
			err.setErrorContactDetail("Reason required!");
		} 
		
		err.setValid(valid);
		
		return err;
	}
	
	private void doProcess(HttpServletRequest req, HttpServletResponse res) {
		String address = "/WEB-INF/MakeBooking.jsp";
		
		SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy");
		String type = req.getParameter("type");
		
		if ( type == null ) type = "ClassRoom";
		req.setAttribute("type", type);
		
		// Get the Facility List based on the Type
		FacilityManager fm = new FacilityManager();
		ArrayList<FacilityDTO> facilities = fm.getFacilityByType(type);
		PriorityManager pm = new PriorityManager();
		ArrayList<PriorityDTO> priorities = pm.getAll();
		
		// Get the data
		BookingErrorDTO err = doValidate(req, res);
		boolean valid = err.isValid();
		
		//System.out.println("Error: " + err);
		//System.out.println("Valid: " + valid);
		System.out.println("Emergency: " + req.getParameter("emergency"));
		
		BookingDTO book = new BookingDTO();
		
		req.setAttribute("facilities", facilities);
		req.setAttribute("priorities", priorities);
		
		BookingManager bm = new BookingManager();
		
		book.setFacilityName(req.getParameter("facility"));
		try {
			book.setStartDate(df.parse(req.getParameter("startDate")));
			book.setEndDate(df.parse(req.getParameter("endDate")));
			book.setPriority(Integer.parseInt(req.getParameter("priority")));
		} catch (Exception e) {
			e.printStackTrace();
		}
		book.setUserId(req.getParameter("userId"));
		book.setContactDetail(req.getParameter("contactDetail"));
		book.setReason(req.getParameter("reason"));
		book.setEmergency(Boolean.valueOf(req.getParameter("emergency")));
		
		UserDTO user = (UserDTO)req.getSession().getAttribute("user");
		
		System.out.println(user);
		if ( user.getManagerId() == null || user.getManagerId().trim().isEmpty() ) {
			book.setStatus("Approve");
			book.setValidateBy(user.getId());
			book.setValidateOn(Calendar.getInstance().getTime());
		} else {
			book.setStatus("Book");
		}
		
		req.setAttribute("booking", book);		
		req.setAttribute("error", err);

		if ( valid ) {
			String error = bm.insertBooking(book);
			err.setErrorGeneral(error);
			
			System.out.println("Booking: " + book);
			System.out.println("Error  : " + error);
			req.setAttribute("error", err);

			if ( error.trim().equals("") ) {
				//sendNotification((UserDTO)req.getSession().getAttribute("user"), book.getEmergency());
				
				address = "ViewCurrentBooking";
				UrlUtility.redirectPage(res, address);
			} else {
				req.setAttribute("errGeneral", error);
				UrlUtility.forwardPage(req, res, address);
			}
			
		} else {
			UrlUtility.forwardPage(req, res, address);
		}
	}

	private void sendNotification(UserDTO user, boolean emergency) {
		if ( user.getManagerId() != null ) {
			UserManager um = new UserManager();
			UserDTO manager = um.getUser(user.getManagerId());
			
			Calendar now = Calendar.getInstance();
			Calendar deadline = Calendar.getInstance();
			
			SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy");
			
			if ( emergency ) {
				deadline.add(Calendar.HOUR, 3);
			} else {
				deadline.add(Calendar.DAY_OF_YEAR, 2);
			}
			
			String subject = "[Facility Booking System] " + (emergency ? "[Important]" : "") + " Approval Required";  
			String message = "Dear " + manager.getName() + ", \n\n " +
			                 "You have facility request to be approved by " + df.format(deadline.getTime()) +
			                 "\n\nPlease kindly log in to the system before the deadline above.";
			
			EmailUtility.sendEmail(user.getEmail(), manager.getEmail(), subject, message);
		}
		
		
		
	}
	
}
